#include "ExpansionPortModule.h"

#include <string.h>

Expansion_Port_Ctrl_Def ch423s_port_ctrl_obj;
// 端口状态,用于参数传递。高4位是边沿状态，0是下降沿，其余为上升沿。低四位是电平状态。0是低电平，其余高电平
uint8_t port_status[32];
rt_thread_t ch423s_tid;

// 负责扩展芯片状态的读取和写入
void Expansion_Flash_Thread(void *parmameter) {
  for (;;) {// 任务主循环
            // 检查初始化状态
	  if ( STATU_GET_NOT( ch423s_port_ctrl_obj.expansion_port_chip_status, CHIP_INIT) ){
		  STATU_SET(ch423s_port_ctrl_obj.expansion_port_chip_status, CHIP_INIT);
	  }
	  rt_thread_mdelay(100);

  }// 任务主循环
}// 负责扩展芯片状态的读取和写入

// 写入状态
rt_err_t Write_Port_Sataus_Interface(Expansion_Port_Ctrl_Def *obj, uint8_t port_group, uint32_t port, bool pin_status) {

  rt_err_t res = RT_EOK;
  // 锁定资源。
  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    uint8_t get_mutex = 0;
    while (rt_mutex_take(&(obj->device_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
      if (get_mutex >= 3) {
        return RT_EBUSY;
      }
      get_mutex++;
    }
  }

  // 写入端口状态
  memset(obj->i2c_ctrl_obj.data_buf, 0, sizeof(obj->i2c_ctrl_obj.data_buf));
  obj->i2c_ctrl_obj.send_data_len = 1;
  obj->i2c_ctrl_obj.receive_data_len = 0;

  if (port_group == IO_PORT_GROUP_1) {
    if (0x01 <= port && port <= 0xFF) {
			if ( pin_status ) {
					STATU_SET(obj->io_port_status, port);
			}else{
					STATU_RESET(obj->io_port_status, port);
			}
			
			if ( port == STATU_IO_3 ) {
				obj->i2c_ctrl_obj.data_buf[1] = obj->io_port_status;
				I2C_Master_Translate_IT(obj->i2c_ctrl_obj.i2c_cm, &(obj->i2c_ctrl_obj), 0x60);
			}
      
    }

  } else if (port_group == OUT_PORT_GROUP_1) {
    if (0x01 <= port && port <= 0xFF) {
      if (pin_status) {
        STATU_SET(obj->out_port_status, port);
      } else {
        STATU_RESET(obj->out_port_status, port);
      }
      obj->i2c_ctrl_obj.data_buf[1] = obj->out_port_status & 0xFF;
      I2C_Master_Translate_IT(obj->i2c_ctrl_obj.i2c_cm, &(obj->i2c_ctrl_obj), 0x44);
    } else if (0x100 <= port && port <= 0xFF00) {
      if (pin_status) {
        STATU_SET(obj->out_port_status, port);
      } else {
        STATU_RESET(obj->out_port_status, port);
      }
      obj->i2c_ctrl_obj.data_buf[1] = (obj->out_port_status >> 8) & 0xFF;
      I2C_Master_Translate_IT(obj->i2c_ctrl_obj.i2c_cm, &(obj->i2c_ctrl_obj), 0x46);
    }
  }


  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    rt_mutex_release(&(obj->device_lock));
  }
  return res;
}// 写入状态

// 等待引脚中断
rt_err_t Wait_For_Port_Intc_Interface(Expansion_Port_Ctrl_Def *obj, uint8_t port_group, uint32_t port, void *params) {
  rt_err_t res = RT_EOK;
  // 锁定资源。
  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    uint8_t get_mutex = 0;
    while (rt_mutex_take(&(obj->device_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
      if (get_mutex >= 3) {
        return RT_EBUSY;
      }
      get_mutex++;
    }
  }

  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    rt_mutex_release(&(obj->device_lock));
  }
  return res;
}// 等待引脚中断

// 读取状态字
rt_err_t Read_Status_Reg_Interface(Expansion_Port_Ctrl_Def *obj) {
  rt_err_t res = RT_EOK;
  // 锁定资源。
  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    uint8_t get_mutex = 0;
    while (rt_mutex_take(&(obj->device_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
      if (get_mutex >= 3) {
        return RT_EBUSY;
      }
      get_mutex++;
    }
  }

  // 读取状态字
  memset(obj->i2c_ctrl_obj.data_buf, 0, sizeof(obj->i2c_ctrl_obj.data_buf));
  obj->i2c_ctrl_obj.send_data_len = 0;
  obj->i2c_ctrl_obj.receive_data_len = 1;
  I2C_Master_Translate_IT(obj->i2c_ctrl_obj.i2c_cm, &(obj->i2c_ctrl_obj), 0x48);
  ULOG_DEBUG("read ch423s reg: 0x%02X\n", obj->i2c_ctrl_obj.data_buf[1]);

  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    rt_mutex_release(&(obj->device_lock));
  }
  return res;
}// 读取状态字

// 写入状态字
rt_err_t Write_Status_Reg_Interface(Expansion_Port_Ctrl_Def *obj) {
  rt_err_t res = RT_EOK;
  // 锁定资源。
  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    uint8_t get_mutex = 0;
    while (rt_mutex_take(&(obj->device_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
      if (get_mutex >= 3) {
        return RT_EBUSY;
      }
      get_mutex++;
    }
  }

  // 写入状态字
  memset(obj->i2c_ctrl_obj.data_buf, 0, sizeof(obj->i2c_ctrl_obj.data_buf));
  obj->i2c_ctrl_obj.data_buf[1] = obj->chip_reg;
  obj->i2c_ctrl_obj.send_data_len = 1;
  obj->i2c_ctrl_obj.receive_data_len = 0;
  I2C_Master_Translate_IT(obj->i2c_ctrl_obj.i2c_cm, &(obj->i2c_ctrl_obj), 0x48);

  if (strlen(obj->device_lock.parent.parent.name) != 0) {// 只有初始化了保护锁才会检查
    rt_mutex_release(&(obj->device_lock));
  }
  return res;
}// 写入状态字

void INT_SRC_Expansion_Port_I2C_RXI_IrqCallback(void) {
  INT_SRC_I2Cx_RXI_IrqCallback(ch423s_port_ctrl_obj.i2c_ctrl_obj.i2c_cm, &(ch423s_port_ctrl_obj.i2c_ctrl_obj));
}

void INT_SRC_Expansion_Port_I2C_TXI_IrqCallback(void) {
  INT_SRC_I2Cx_TXI_IrqCallback(ch423s_port_ctrl_obj.i2c_ctrl_obj.i2c_cm, &(ch423s_port_ctrl_obj.i2c_ctrl_obj));
}

void INT_SRC_Expansion_Port_I2C_TEI_IrqCallback(void) {
  INT_SRC_I2Cx_TEI_IrqCallback(ch423s_port_ctrl_obj.i2c_ctrl_obj.i2c_cm, &(ch423s_port_ctrl_obj.i2c_ctrl_obj));
}

void INT_SRC_Expansion_Port_I2C_EEI_IrqCallback(void) {
  INT_SRC_I2Cx_EEI_IrqCallback(ch423s_port_ctrl_obj.i2c_ctrl_obj.i2c_cm, &(ch423s_port_ctrl_obj.i2c_ctrl_obj));
}

// 初始化结构体
void Init_Expansion_Port(Expansion_Port_Ctrl_Def *obj, CM_I2C_TypeDef *CM_I2Cx, char *name) {

  char build_buf[32];

  STATU_SET(obj->chip_reg, X_INT);
	STATU_SET(obj->chip_reg, IO_OE);
	strcpy(obj->name, name);

  memset(build_buf, 0, 32);
  rt_sprintf(build_buf, "%s_i2c", name);
  Init_I2c_Data_Task_Obj(&(obj->i2c_ctrl_obj), build_buf, CM_I2Cx);
  memset(build_buf, 0, 32);
  rt_sprintf(build_buf, "%s_device_lock", name);
  rt_mutex_init(&(obj->device_lock), build_buf, RT_IPC_FLAG_PRIO);
	
	obj->i2c_ctrl_obj.has_address = false;
	
	obj->io_port_status = 0xFF;
	obj->out_port_status = 0xFFFF;

  obj->Write_Port_Sataus = Write_Port_Sataus_Interface;
  obj->Wait_For_Port_Intc = Wait_For_Port_Intc_Interface;
  obj->Write_Status_Reg = Write_Status_Reg_Interface;
  obj->Read_Status_Reg = Read_Status_Reg_Interface;
	
	// rtc_tid任务
  ch423s_tid = rt_thread_create("Rtc Check Task",
                                   Expansion_Flash_Thread, RT_NULL,
                                   THREAD_STACK_SIZE,
                                   27, THREAD_TIMESLICE);
  // 这里优先级要低于别的任务，保证所有任务都收到引脚通知
  if (ch423s_tid != RT_NULL &&
      (strlen(ch423s_port_ctrl_obj.name) > 0 && strlen(ch423s_port_ctrl_obj.i2c_ctrl_obj.name) > 0)) {
    //rt_thread_startup(ch423s_tid);
	}
}// 初始化结构体
